home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * flrle.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
- *
- * flrle.c: Library routines for reading and Writing Utah RLE
- * raster toolkit format.
- *
- * CONTENTS
- * read_rle (image, rfile, mstr, mlen)
- * write_rle (image, wfile)
- *
- * EDITLOG
- * LastEditDate = Mon Jun 25 00:05:13 1990 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm/flrle.c
- *
- * HISTORY
- * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
- * Package for Release 1.0
- *
- * 13-Aug-89 Paul Milazzo (milazzo@diamond.bbn.com) BBN
- * Created.
- *****************************************************************/
-
- #include <stdio.h>
- #include "fbm.h"
-
- #ifndef lint
- static char *fbmid =
- "$FBM flrle.c <1.0> 25-Jun-90 by Paul Milazzo, source code available \
- free from MLM@CS.CMU.EDU and from UUNET archives$";
- #endif
-
- #ifdef RLE
-
- #include "svfb_global.h"
-
- #define CMAP_COLORS 3
-
- #define TITLE_COMMENT "TITLE"
- #define CREDITS_COMMENT "CREDITS"
- #define ASPECT_COMMENT "aspect_ratio"
- #define CMAP_COMMENT "color_map_length"
- #define MAX_COMMENTS 4
- #define MAX_LABEL_LENGTH (sizeof (CMAP_COMMENT))
-
- #define TRUE 1
- #define FALSE 0
-
- static char *CommentBuf (bpp)
- char **bpp;
- {
- char *bp;
-
- if ((bp = (char *)malloc (FBM_MAX_TITLE + MAX_LABEL_LENGTH)) ==
- (char *)NULL)
- {
- perror ("Can't allocate space for RLE comment");
- exit (1);
- }
-
- *bpp = bp;
-
- return bp;
- }
-
- /****************************************************************
- * write_rle (image, wfile)
- ****************************************************************/
-
- write_rle (image, wfile)
- FBM *image;
- FILE *wfile;
- {
- rle_pixel **rowvec;
- char *comments[MAX_COMMENTS + 1];
- char **cp = comments;
- rle_map *colorMap = (rle_map *)NULL;
- int channel;
- int i;
- int j;
- int rows;
- int cols;
- int planes;
- int rowlen;
- int plnlen;
-
- if (image->hdr.physbits != 8) {
- fputs ("write_rle: error: can only handle 8 physical bits per pixel\n",
- stderr);
- return (0);
- }
-
- rows = image->hdr.rows;
- cols = image->hdr.cols;
- planes = image->hdr.planes;
- rowlen = image->hdr.rowlen;
- plnlen = image->hdr.plnlen;
-
- sv_globals.sv_ncolors = planes;
- sv_globals.sv_alpha = 0; /* no alpha channel */
- sv_globals.sv_background = 2; /* clear background to sv_bg_color */
- sv_globals.sv_xmin = 0;
- sv_globals.sv_xmax = cols - 1;
- sv_globals.sv_ymin = 0;
- sv_globals.sv_ymax = rows - 1;
- sv_globals.sv_cmaplen = 0; /* log2(color_map_length) */
- if (image->hdr.clrlen > 0) {
- sv_globals.sv_ncmap = CMAP_COLORS;
-
- for (i = 1; i < image->hdr.clrlen / CMAP_COLORS; i <<= 1)
- sv_globals.sv_cmaplen++;
-
- if ((colorMap = (rle_map *)malloc(image->hdr.clrlen*sizeof(rle_map))) ==
- (rle_map *)NULL)
- {
- perror ("write_rle: can't allocate RLE color map");
- return 0;
- }
- for (i = 0; i < image->hdr.clrlen; i++)
- colorMap[i] = (rle_map)image->cm[i] << 8;
- sv_globals.sv_cmap = colorMap;
- }
- else {
- sv_globals.sv_ncmap = 0;
- sv_globals.sv_cmap = (rle_map *)NULL;
- }
-
- for (channel = 0; channel < planes; channel++)
- SV_SET_BIT (sv_globals, channel);
-
- if (*image->hdr.title != '\0')
- sprintf (CommentBuf (cp++), "%s=%s",
- TITLE_COMMENT, image->hdr.title);
-
- if (*image->hdr.credits != '\0')
- sprintf (CommentBuf (cp++), "%s=%s",
- CREDITS_COMMENT, image->hdr.credits);
-
- if (image->hdr.aspect != 1.0)
- sprintf (CommentBuf (cp++), "%s=%g",
- ASPECT_COMMENT, image->hdr.aspect);
-
- /*
- * If the color map length is not a power of two, put the actual length
- * in a comment.
- */
- if (image->hdr.clrlen > 0 &&
- (1 << sv_globals.sv_cmaplen) != image->hdr.clrlen / CMAP_COLORS)
- {
- sprintf (CommentBuf (cp++), "%s=%d",
- CMAP_COMMENT, image->hdr.clrlen / CMAP_COLORS);
- }
-
- *cp = (char *)NULL;
-
- sv_globals.sv_comments = cp > comments ? comments : (char **)NULL;
-
- sv_globals.svfb_fd = wfile;
-
- sv_setup (RUN_DISPATCH, &sv_globals);
-
- if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
- (unsigned char **)NULL)
- {
- perror ("write_rle: can't allocate row indirection vectors");
- return 0;
- }
-
- for (j = rows - 1; j >= 0; --j) {
- for (channel = 0; channel < planes; channel ++)
- rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
- sv_putrow (rowvec, cols, &sv_globals);
- }
- sv_puteof (&sv_globals);
-
- free (rowvec);
- while (cp > comments)
- free (*--cp);
- if (colorMap != (rle_map *)NULL)
- free (colorMap);
-
- return 1;
- }
-
- /****************************************************************
- * read_rle (image, rfile)
- ****************************************************************/
-
- read_rle (image, rfile, mstr, mlen)
- FBM *image;
- FILE *rfile;
- char *mstr;
- int mlen;
- {
- rle_pixel **colorMap;
- rle_pixel **rowvec;
- unsigned char *cp;
- char *comment;
- int j;
- int channel;
- int rows;
- int planes;
- int rowlen;
- int plnlen;
- int mapEntries;
- int clearRow;
-
- /* must put the magic number back so the setup code can read it */
- while (mlen--)
- (void)ungetc (*mstr++, rfile);
-
- sv_globals.svfb_fd = rfile;
- switch (rle_get_setup (&sv_globals)) {
- case 0:
- break; /* success */
- case -1:
- fputs ("read_rle: input is not a Utah RLE file.\n", stderr);
- /* fall through... */
- case -2:
- return 0; /* sv_get_setup already printed an error message */
- case -3:
- fputs ("read_rle: input file is empty.\n", stderr);
- return 0;
- case -4:
- fputs ("read_rle: end-of-file encountered while reading RLE header.\n",
- stderr);
- return 0;
- default:
- fputs ("read_rle: rle_get_setup returned something strange!\n",
- stderr);
- }
-
- if (sv_globals.sv_alpha) {
- fputs ("read_rle: discarding alpha channel.\n", stderr);
- SV_CLR_BIT (sv_globals, SV_ALPHA);
- }
-
- image->hdr.cols = sv_globals.sv_xmax - sv_globals.sv_xmin + 1;
- image->hdr.rows = rows = sv_globals.sv_ymax - sv_globals.sv_ymin + 1;
- image->hdr.planes = planes = sv_globals.sv_ncolors;
- image->hdr.bits = sv_globals.sv_cmaplen ? sv_globals.sv_cmaplen : 8;
- image->hdr.physbits = 8;
- image->hdr.rowlen = rowlen = image->hdr.cols;
- image->hdr.plnlen = plnlen = image->hdr.rows * image->hdr.rowlen;
-
- image->hdr.clrlen = 1 << sv_globals.sv_cmaplen;
- if ((comment = rle_getcom (CMAP_COMMENT, &sv_globals)) != (char *)NULL)
- image->hdr.clrlen = atoi (comment);
- image->hdr.clrlen *= sv_globals.sv_ncmap;
-
- if ((comment = rle_getcom (ASPECT_COMMENT, &sv_globals)) != (char *)NULL)
- image->hdr.aspect = atof (comment);
- else
- image->hdr.aspect = 1.0;
-
- if ((comment = rle_getcom (TITLE_COMMENT, &sv_globals)) != (char *)NULL)
- (void)strcpy (image->hdr.title, comment);
- else
- image->hdr.title[0] = '\0';
- if ((comment = rle_getcom (CREDITS_COMMENT, &sv_globals)) != (char *)NULL)
- (void)strcpy (image->hdr.credits, comment);
- else
- image->hdr.credits[0] = '\0';
-
- image->cm = (unsigned char *)NULL;
- image->bm = (unsigned char *)NULL;
- alloc_fbm (image);
-
- if (image->hdr.clrlen > 0) {
- mapEntries = (image->hdr.clrlen / sv_globals.sv_ncmap);
- cp = image->cm;
- colorMap = buildmap (&sv_globals, CMAP_COLORS, 1.0);
- for (channel = 0; channel < CMAP_COLORS; channel++) {
- for (j = 0; j < mapEntries; j++)
- *cp++ = colorMap[channel][j];
- free (colorMap[channel]);
- }
- free (colorMap);
- image->hdr.clrlen = mapEntries * CMAP_COLORS; /* renormalize clrlen */
- }
-
- switch (sv_globals.sv_background) {
- case 0: /* no background color was saved */
- clearRow = TRUE; /* manually clear rows to 0 */
- break;
- case 1: /* don't clear to the background color */
- sv_globals.sv_background = 2; /* force automatic clearing */
- /* fall through... */
- case 2: /* clear to the background color */
- clearRow = FALSE;
- break;
- default:
- fprintf (stderr, "read_rle: unknown background flag '%d'.\n",
- sv_globals.sv_background);
- }
-
- /* move image to origin */
- sv_globals.sv_xmin = 0;
- sv_globals.sv_xmax = image->hdr.cols - 1;
- sv_globals.sv_ymin = 0;
- sv_globals.sv_ymax = image->hdr.rows - 1;
-
- if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
- (unsigned char **)NULL)
- {
- perror ("write_rle: can't allocate row indirection vectors");
- return 0;
- }
-
- for (j = rows - 1; j >= 0; --j) {
- for (channel = 0; channel < planes; channel ++) {
- rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
- if (clearRow)
- bzero ((char *)rowvec[channel], rowlen);
- }
- rle_getrow (&sv_globals, rowvec);
- }
- free (rowvec);
-
- return 1;
- }
-
- #else /* ! RLE */
-
- /*ARGSUSED*/
- write_rle (image, wfile)
- FBM *image;
- FILE *wfile;
- {
- fputs ("RLE support was omitted at compile time.\n", stderr);
- }
-
- /*ARGSUSED*/
- read_rle (image, rfile, mstr, mlen)
- FBM *image;
- FILE *rfile;
- char *mstr;
- int mlen;
- {
- write_rle (image, rfile);
- }
-
- #endif /* RLE */
-